-------------------------------------------------------------------------------
-- Archivo: 			         fft_fsm.vhdl
-- Fecha de creación:            25/01/2011
-- Última fecha de modificación: 28/01/2011
-- Diseñador: 			         Cesar A. Fuguet T.
-- Diseño: 			             fft_fsm
-- Propósito: 			         Máquina de estados para el control durante la
--                               ejecución de una instrucción FFT
-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;

entity fft_fsm is
  
    port (
        COUNTER_i   : in  std_logic_vector(1 downto 0);
        OPCODE_i    : in  std_logic_vector(3 downto 0);
        CLK_i       : in  std_logic;
        RESET_i     : in  std_logic;
        FFT_STG_o   : out std_logic_vector(2 downto 0));

end fft_fsm;

architecture fsm of fft_fsm is
    constant FFT_OPCODE : std_logic_vector(3 downto 0) := "1111";

    constant FFT_STAGE0 : std_logic_vector(2 downto 0) := "000";
    constant FFT_STAGE1 : std_logic_vector(2 downto 0) := "001";
    constant FFT_STAGE2 : std_logic_vector(2 downto 0) := "010";
    constant FFT_STAGE3 : std_logic_vector(2 downto 0) := "011";
    constant FFT_IDLE : std_logic_vector(2 downto 0) := "111";

    signal input : std_logic;
    signal curr_state : std_logic_vector(2 downto 0);
    signal next_state : std_logic_vector(2 downto 0);
  
begin  -- fsm

    input <= '1' when (COUNTER_i = "11" and OPCODE_i = FFT_OPCODE) else
           '0';

    --COUNTER_i(0) and COUNTER_i(1) and OPCODE_i(0)
    --         and OPCODE_i(1) and OPCODE_i(2) and OPCODE_i(3);

    next_state <= 
        FFT_STAGE1 when input = '1' and curr_state = FFT_STAGE0 else
        FFT_IDLE   when input = '1' and curr_state = FFT_STAGE1 else
        FFT_STAGE2 when input = '1' and curr_state = FFT_IDLE   else
        FFT_STAGE3 when input = '1' and curr_state = FFT_STAGE2 else
        FFT_STAGE0 when input = '1' and curr_state = FFT_STAGE3 else
        curr_state;

    curr_state_process: process (CLK_i, RESET_i, next_state)
    begin
    if CLK_i'event and CLK_i = '1' then
        if RESET_i = '1' then
            curr_state <= FFT_STAGE0;
        else
            curr_state <= next_state;
        end if;
    end if;
    end process curr_state_process;

    FFT_STG_o <= curr_state;
  
end fsm;

-- vim: tabstop=4 : expandtab : shiftwidth=4
